home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Science⁄Math / Scientist's Helper src / s.helper.3 / regio.c < prev   
C/C++ Source or Header  |  1986-02-06  |  19KB  |  851 lines

  1. #include "all.h"
  2. #include "regtabext.h"
  3.  
  4. WriteGraph(reply)
  5. SFReply *reply;
  6. {
  7.     int f, i, j, k, vsize, hsize;
  8.     char str[256];
  9.     long count, bytesAvailable, pntg, mpnt, dstBytes;
  10.     Finfo info;
  11.     char dstbuf[512], srcbuf[512];
  12.     char *srcPtr, *dstPtr, *mypointer;
  13.     
  14.     if( !(reply->good) ) {
  15.         return;
  16.         }
  17.  
  18.     strncpy( &pntg, "PNTG", 4 );
  19.     strncpy( &mpnt, "MPNT", 4 );
  20.     
  21.     if( GetFInfo( reply->fName, reply->vRefNum, &info )==noErr ) { /*delete old file, if any*/
  22.         if(  info.fdType!=pntg ) {
  23.             ErrMsg("cant overwrite a non-Paint file");
  24.             }
  25.         else {
  26.             if( FSDelete(reply->fName, reply->vRefNum)!=noErr ) {
  27.                 ErrMsg("couldnt delete existing file");
  28.                 }
  29.             }
  30.         }
  31.         
  32.     bytesAvailable = 0;
  33.     for( i=0; i<10; i++ ) {
  34.         k=GetVInfo( i, str, &j, &count );
  35.         if( (k==noErr) && (j==reply->vRefNum) ) {
  36.             bytesAvailable=count;
  37.             break;
  38.             }
  39.         }
  40.         
  41.     /* I really should check here if there is enough space on disk */
  42.     /* but I dont really see how to do this without compressing the entire bit map first*/
  43.         
  44.     if( Create(reply->fName, reply->vRefNum, mpnt, pntg)!=noErr ) {
  45.         ErrMsg("couldnt create file");
  46.         }
  47.         
  48.     if( FSOpen(reply->fName, reply->vRefNum, &f )!=noErr ) {
  49.         ErrMsg("couldnt open file");
  50.         }
  51.  
  52.     if( SetFPos( f, fsFromStart, 0L )!=noErr ) {
  53.         ErrMsg("couldnt find beginning of file");
  54.         }
  55.  
  56.     for( i=0; i<512; i++ ) { /*header is block of 512 nulls*/
  57.         dstbuf[i]=0;
  58.         }
  59.     count=512L;
  60.     k = FSWrite(f, &count, &dstbuf[0] );
  61.     if( (k!=noErr) || (count!=512L) ){
  62.         FSClose(f);
  63.         ErrMsg("couldnt write graph");
  64.         }
  65.         
  66.     mypointer = grMap.baseAddr;
  67.     hsize = grMap.rowBytes;
  68.     vsize = grMap.bounds.bottom - grMap.bounds.top;
  69.     
  70.     for( j=1; j<=720; j++ ) {
  71.         srcPtr = &srcbuf[0];
  72.         dstPtr = &dstbuf[0];
  73.         for( i=0; i<72; i++ ) {
  74.             if( (i<hsize) && (j<=vsize) ) {
  75.                 srcbuf[i]=*mypointer;
  76.                 mypointer++;
  77.                 }
  78.             else {
  79.                 srcbuf[i] = 0;
  80.                 }
  81.             }
  82.         PackBits( &srcPtr, &dstPtr,72);
  83.         dstBytes = (long)(dstPtr-&dstbuf[0]);
  84.         count = dstBytes;
  85.         k = FSWrite(f, &count, &dstbuf[0] );
  86.         if( (k!=noErr) || (count!=dstBytes) ){
  87.             FSClose(f);
  88.             ErrMsg("couldnt write graph");
  89.             }
  90.         } /*end for*/
  91.  
  92.     if( FSClose(f)!=noErr ) {
  93.         ErrMsg("couldnt close file");
  94.         }
  95.         
  96.     FlushVol( str, reply->vRefNum );
  97. }
  98.  
  99. ReadProcedure(reply)
  100. SFReply *reply;
  101. {
  102.     char        str[512];
  103.     int        i, j, k, f, oldWindow;
  104.     long        regTabType, count;
  105.     Finfo     info;
  106.     GrafPtr    oldPort;
  107.     
  108.     if( !(reply->good) ) {
  109.         return;
  110.         }
  111.     
  112.     strncpy( (char*)(®TabType), "TEXT", 4 );
  113.     
  114.     if( GetFInfo( reply->fName, reply->vRefNum, &info )!=noErr ) {
  115.         ErrMsg("couldnt get file info");
  116.         }
  117.     if(  info.fdType!=regTabType ) {
  118.         ErrMsg("not a Text file");
  119.         }
  120.  
  121.     /*open file*/
  122.     
  123.     if( FSOpen( reply->fName, reply->vRefNum, &f)!=noErr ) {
  124.         ErrMsg("couldnt open file");
  125.         }
  126.     SetFPos( f, fsFromStart, 0L );
  127.     
  128.     GetPort(&oldPort);
  129.     oldWindow=currentWindow;
  130.     
  131.     currentWindow=prWindow;
  132.     whichWindow=theWindow[prWindow];
  133.     SetPort(whichWindow);
  134.     
  135.     TESetSelect( (long)((*prText)->teLength),(long)((*prText)->teLength),prText);
  136.     TEKey( '\r', prText );
  137.     TEKey( '\r', prText );
  138.     
  139.     for( i=0; i<63; i++ ) {
  140.         count=512L;
  141.         k=FSRead(f,&count,str);
  142.         if( (k==noErr) || (k==eofErr) ) {
  143.             TEInsert( str, count, prText );
  144.             }
  145.         else {
  146.             break;
  147.             }
  148.         if( count<512L ) {
  149.             break;
  150.             }
  151.         } /*end for*/
  152.     FSClose(f);
  153.     IfOutScroll(prText);
  154.     
  155.     SetPort( oldPort );
  156.     currentWindow=oldWindow;
  157.     whichWindow=theWindow[currentWindow];
  158. }
  159.  
  160.  
  161. WriteProcedure(reply)
  162. SFReply *reply;
  163. {
  164.     int f, i, j, k;
  165.     char str[256];
  166.     long count, bytesNeeded, bytesAvailable, regTabType;
  167.     Finfo info;
  168.     
  169.     if( !(reply->good) ) {
  170.         return;
  171.         }
  172.  
  173.     strncpy( ®TabType, "TEXT", 4 );
  174.     
  175.     if( GetFInfo( reply->fName, reply->vRefNum, &info )==noErr ) { /*delete old file, if any*/
  176.         if(  info.fdType!=regTabType ) {
  177.             ErrMsg("cant overwrite a non-Text file");
  178.             }
  179.         else {
  180.             if( FSDelete(reply->fName, reply->vRefNum)!=noErr ) {
  181.                 ErrMsg("couldnt delete existing file");
  182.                 }
  183.             }
  184.         }
  185.         
  186.     bytesNeeded = (*prText)->teLength;
  187.     bytesAvailable = 0;
  188.     for( i=0; i<10; i++ ) {
  189.         k=GetVInfo( i, str, &j, &count );
  190.         if( (k==noErr) && (j==reply->vRefNum) ) {
  191.             bytesAvailable=count;
  192.             break;
  193.             }
  194.         }
  195.     if( bytesAvailable<bytesNeeded ) {
  196.         ErrMsg( "not enough space on disk" );
  197.         }
  198.         
  199.     if( Create(reply->fName, reply->vRefNum, regTabType, regTabType)!=noErr ) {
  200.         ErrMsg("couldnt create file");
  201.         }
  202.         
  203.     if( FSOpen(reply->fName, reply->vRefNum, &f )!=noErr ) {
  204.         ErrMsg("couldnt open file");
  205.         }
  206.  
  207.     if( SetFPos( f, fsFromStart, 0L )!=noErr ) {
  208.         ErrMsg("couldnt find beginning of file");
  209.         }
  210.  
  211.     count=bytesNeeded;
  212.     HLock( (*prText)->hText );
  213.     k = FSWrite(f, &count, *((*prText)->hText) );
  214.     HUnlock( (*prText)->hText );
  215.     
  216.     if( (k!=noErr) || (count!=bytesNeeded) ){
  217.         FSClose(f);
  218.         ErrMsg("couldnt write procedure");
  219.         }
  220.  
  221.     if( FSClose(f)!=noErr ) {
  222.         ErrMsg("couldnt close file");
  223.         }
  224.         
  225.     FlushVol( str, reply->vRefNum );
  226. }
  227.  
  228. ReadAsciiTable(reply)
  229. SFReply *reply;
  230. {
  231.     char        cLast, str[512], s[80];
  232.     int        i, j, k, f, lines, columns, firstReturn;
  233.     long        regTabType, count;
  234.     Finfo     info;
  235.     float    x;
  236.     GrafPtr    oldPort;
  237.     
  238.     if( !(reply->good) ) {
  239.         return;
  240.         }
  241.         
  242.     GetPort(&oldPort);
  243.     SetPort( theWindow[edWindow] );
  244.     InvalRect( &(theWindow[edWindow]->portRect) );
  245.     SetPort( oldPort );
  246.     
  247.     strncpy( (char*)(®TabType), "TEXT", 4 );
  248.     
  249.     if( GetFInfo( reply->fName, reply->vRefNum, &info )!=noErr ) {
  250.         ErrMsg("couldnt get file info");
  251.         }
  252.     if(  info.fdType!=regTabType ) {
  253.         ErrMsg("not a Text file");
  254.         }
  255.  
  256.     /*open file*/
  257.     
  258.     if( FSOpen( reply->fName, reply->vRefNum, &f)!=noErr ) {
  259.         ErrMsg("couldnt open file");
  260.         }
  261.     SetFPos( f, fsFromStart, 0L );
  262.     
  263.     /* determine size of table*/
  264.     lines = 0;
  265.     columns = 0;
  266.     i=0;  /*counts tabs per line*/
  267.     j=0; /*counts characters*/
  268.     cLast='\0';
  269.     firstReturn=TRUE;
  270.     while( lines<=4097 ) {    /*loop over lines in file */
  271.         count=1L;
  272.         k=FSRead(f,&count,str);
  273.         if( (count!=1L) || (k!=noErr) ) {
  274.             if( (cLast=='\r') || (!firstReturn) ) {
  275.                 break;
  276.                 }
  277.             else {
  278.                 str[0]='\r';
  279.                 firstReturn=FALSE;
  280.                 }
  281.             }
  282.         j++;
  283.         cLast=str[0];
  284.         if( str[0]=='\t') {
  285.             i++;
  286.             }
  287.         else if( str[0]=='\r' ) {
  288.             lines++;
  289.             if( i>columns ) {
  290.                 columns=i;
  291.                 }
  292.             i=0;
  293.             } /*end if*/
  294.         } /*end while*/
  295.         columns++; /*since tabs were counted*/
  296.         if( columns>32 ) {
  297.             columns=32;
  298.             }
  299.         lines--;  /*since first line is colnames*/
  300.     FSClose(f);
  301.     
  302.     /* set up table header */
  303.     if( (lines>table.header.rows) || (columns>table.header.cols) ) {
  304.         AllocTable( lines, columns );
  305.         WriteLine("Warning: table allocation changed");
  306.         }
  307.     else {
  308.         table.header.rows = lines;
  309.         table.header.cols = columns;
  310.         }
  311.     table.header.interpolated = FALSE;
  312.     for( i=1; i<=table.header.cols; i++ ) {
  313.         strcpy( s, "Col " );
  314.         IToS( i, &(s[4]) );
  315.         strcpy( table.header.colName[i-1], s );
  316.         } /*end for*/
  317.     for( i=1; i<=table.header.rows; i++ ) {
  318.     for( j=1; j<=table.header.cols; j++ ) {
  319.         SetTable(i,j,infinity,FALSE);
  320.         }} /*end fors*/
  321.     
  322.     /* now read in the data */
  323.     if( FSOpen( reply->fName, reply->vRefNum, &f)!=noErr ) {
  324.         ErrMsg("couldnt open file");
  325.         }
  326.     SetFPos( f, fsFromStart, 0L );
  327.     
  328.     /*read colnames*/
  329.     i=1;
  330.     s[0]='\0';
  331.     while( i<=table.header.cols ) {
  332.         count=1L;
  333.         k=FSRead(f,&count,str);
  334.         if( (count!=1L) || (k!=noErr) ) {
  335.             break;
  336.             }
  337.         str[1]='\0';
  338.         if( (str[0]=='\t') || (str[0]=='\r')  ) {
  339.             strcpy( table.header.colName[i-1], s );
  340.             i++;
  341.             s[0]='\0';
  342.             if( str[0]=='\r' ) {
  343.                 break;
  344.                 }
  345.             }
  346.         else {
  347.             strcat( s, str );
  348.             }
  349.         } /*end while*/
  350.             
  351.     /*read table entries*/
  352.     i=1;
  353.     s[0]='\0';
  354.     cLast='\0';
  355.     firstReturn=TRUE;
  356.     while( i<=table.header.rows ) {
  357.         j=1;
  358.         while( j<=table.header.cols ) {
  359.             count=1L;
  360.             k=FSRead(f,&count,str);
  361.             if( (count!=1L) || (k!=noErr) ) {
  362.                 if( (cLast=='\r') || (!firstReturn) ) {
  363.                     break;
  364.                     }
  365.                 else {
  366.                     str[0]='\r';
  367.                     firstReturn=FALSE;
  368.                     }
  369.                 }
  370.             str[1]='\0';
  371.             cLast=str[0];
  372.             if( (str[0]=='\t') || (str[0]=='\r')  ) {
  373.                 SToR( s, &x, TRUE );
  374.                 SetTable(i,j,x,TRUE);
  375.                 j++;
  376.                 s[0]='\0';
  377.                 if( str[0]=='\r' ) {
  378.                     i++;
  379.                     break;
  380.                     }
  381.                 }
  382.             else {
  383.                 strcat( s, str );
  384.                 }
  385.             } /*end while j*/
  386.         } /*end while i*/
  387.     FSClose(f);
  388.     Header2Vars();
  389. }
  390.  
  391. WriteAsciiTable(reply)
  392. SFReply *reply;
  393. {
  394.     int f, i, j, k;
  395.     char str[256];
  396.     long count, bytesNeeded, regTabType;
  397.     Finfo info;
  398.     float x;
  399.     
  400.     if( !(reply->good) ) {
  401.         return;
  402.         }
  403.  
  404.     strncpy( ®TabType, "TEXT", 4 );
  405.     
  406.     if( GetFInfo( reply->fName, reply->vRefNum, &info )==noErr ) { /*delete old file, if any*/
  407.         if(  info.fdType!=regTabType ) {
  408.             ErrMsg("cant overwrite a non-Text file");
  409.             }
  410.         else {
  411.             if( FSDelete(reply->fName, reply->vRefNum)!=noErr ) {
  412.                 ErrMsg("couldnt delete existing file");
  413.                 }
  414.             }
  415.         }
  416.         
  417.     if( Create(reply->fName, reply->vRefNum, regTabType, regTabType)!=noErr ) {
  418.         ErrMsg("couldnt create file");
  419.         }
  420.         
  421.     if( FSOpen(reply->fName, reply->vRefNum, &f )!=noErr ) {
  422.         ErrMsg("couldnt open file");
  423.         }
  424.  
  425.     if( SetFPos( f, fsFromStart, 0L )!=noErr ) {
  426.         ErrMsg("couldnt find beginning of file");
  427.         }
  428.  
  429.     for( i=1; i<=table.header.cols; i++ ) {
  430.         strcpy( str, table.header.colName[i-1] );
  431.         if( i<table.header.cols ) {
  432.             strcat( str, "\t" );
  433.             }
  434.         else {
  435.             strcat( str, "\r" );
  436.             }
  437.         bytesNeeded =  (long) strlen( str );
  438.         count=bytesNeeded;        
  439.         k = FSWrite(f, &count, str );
  440.         if( (k!=noErr) || (count!=bytesNeeded) ){
  441.             FSClose(f);
  442.             ErrMsg("couldnt write colnames");
  443.             }
  444.         } /*end for*/
  445.  
  446.     for( i=1; i<=table.header.rows; i++ ) {
  447.     for( j=1; j<=table.header.cols; j++ ) {
  448.         GetTable(i,j,&x);
  449.         RToS( x, str );
  450.         if( j<table.header.cols ) {
  451.             strcat( str, "\t" );
  452.             }
  453.         else {
  454.             strcat( str, "\r" );
  455.             }
  456.         bytesNeeded =  (long) strlen( str );
  457.         count=bytesNeeded;        
  458.         k = FSWrite(f, &count, str );
  459.         if( (k!=noErr) || (count!=bytesNeeded) ){
  460.             FSClose(f);
  461.             ErrMsg("couldnt write table");
  462.             } /*end if*/
  463.         } } /*end fors*/
  464.  
  465.     if( FSClose(f)!=noErr ) {
  466.         ErrMsg("couldnt close file");
  467.         }
  468.         
  469.     FlushVol( str, reply->vRefNum );
  470. }
  471.  
  472. Mean()
  473. {
  474.     int i, colx, coly, stat;
  475.     float sum, sum2, x, mean, stdDev, n;
  476.     char str1[cmdWordLen], str2[cmdWordLen];
  477.     
  478.     SToI( command.cmdWord[2], &colx );
  479.     sum = 0.0;
  480.     sum2 = 0.0;
  481.     n = 0.0;
  482.     i = 1;
  483.     
  484.     while ( NextNotNan(i,colx,colx,&i) ) {                   
  485.         GetTable(i,colx,&x);
  486.         sum  += x;
  487.         sum2 +=  x*x;
  488.         n += 1.0;
  489.         i++;
  490.         }
  491.         
  492.     mean = sum / n;
  493.     stdDev  = sqrt( (n*sum2 - sum*sum)/(n*(n-1)) );
  494.  
  495.     strcpy(str2,"mean ");
  496.     RToS( mean, str1 );
  497.     stat = SetVar("mean",str1);
  498.     strcat( str2, str1 );
  499.     
  500.     RToS( stdDev, str1 );
  501.     stat = stat && SetVar("stddev",str1);
  502.     strcat(str2, " stddev ");
  503.     strcat(str2, str1 );
  504.     
  505.     RToS( n, str1 );
  506.     stat = stat && SetVar("counts",str1);
  507.     strcat( str2, " counts ");
  508.     strcat( str2, str1 );
  509.  
  510.     if( strcmp(command.cmdWord[1],"type")==0 ) {
  511.         WriteLine(str2);
  512.         }                   
  513.     else if( strcmp(command.cmdWord[1],"keep")==0 ) {
  514.         SToI( command.cmdWord[3], &coly );
  515.         for( i=1; i<=table.header.rows; i++ ) {
  516.             SetTable(i,coly,mean,FALSE);
  517.             }
  518.         }
  519.     else if( strcmp(command.cmdWord[1],"remove")==0 ) {
  520.         SToI( command.cmdWord[3], &coly );
  521.         for( i=1; i<=table.header.rows; i++ ) {
  522.             GetTable(i,colx,&x);
  523.             SetTable(i,coly,(x-mean),FALSE);
  524.             }
  525.     }
  526.     else if( strcmp(command.cmdWord[1],"compute")==0 ) {
  527.         ;
  528.         }
  529.     else {
  530.         ErrMsg(badModifier);
  531.         }
  532.  
  533.     if( !stat ) {
  534.         ErrMsg("couldnt set variables");
  535.         }
  536. }
  537.  
  538.  
  539. Trend()
  540. {
  541.     int i, colx, coly, colz, stat;
  542.     float x, y, sumX, sumY, sumX2, sumY2, sumXY, idata;
  543.     float s0, intercept, slope, errIntercept, errSlope;
  544.     char str1[cmdWordLen], str2[cmdWordLen];
  545.  
  546.     SToI( command.cmdWord[2], &colx );
  547.     SToI( command.cmdWord[3], &coly );
  548.     sumX = 0.0;
  549.     sumY = 0.0;
  550.     sumX2 = 0.0;
  551.     sumY2 = 0.0;
  552.     sumXY = 0.0;
  553.     idata = 0.0;
  554.     
  555.     i = 1;
  556.     while( NextNotNan(i,colx,coly,&i) ) {
  557.         GetTable(i,colx,&x);
  558.         GetTable(i,coly,&y);
  559.         sumX  += x;
  560.         sumY  += y;
  561.         sumX2  += x*x;
  562.         sumY2  += y*y;
  563.         sumXY  += x*y;
  564.         idata += 1.0;
  565.         i++;
  566.         }
  567.  
  568.     slope = (sumXY - (sumX*sumY/idata)) / (sumX2-(sumX*sumX/idata));
  569.     intercept = (sumY/idata) - (slope*(sumX/idata));
  570.  
  571.     s0 = sumY2 - (sumY*sumY/idata) - (slope*(sumXY - sumX*(sumY/idata)));
  572.     s0 = s0 / (idata-2.0);
  573.     errIntercept = sqrt( (double)(s0 * sumX2 / (idata*(sumX2 - (sumX*sumX/idata)))) );
  574.     errSlope = sqrt( (double) (s0 / (sumX2 - (sumX*sumX/idata))) );
  575.  
  576.     RToS(slope,str2);
  577.     stat = SetVar("slope",str2);
  578.     strcpy( str1,"slope ");
  579.     strcat( str1, str2 );
  580.  
  581.     RToS( intercept, str2 );
  582.     stat = stat && SetVar("intercept",str2);
  583.     strcat( str1, " intercept ");
  584.     strcat( str1, str2 );
  585.  
  586.     RToS( idata, str2 );
  587.     stat = stat && SetVar("counts", str2);
  588.     strcat( str1, " counts ");
  589.     strcat( str1, str2 );
  590.  
  591.     if( strcmp(command.cmdWord[1],"type")==0 ) {
  592.         WriteLine(str1);
  593.         }
  594.  
  595.     RToS(errSlope,str2);
  596.     stat = stat && SetVar("errslope",str2);
  597.     strcpy( str1, "errslope ");
  598.     strcat( str1, str2 );
  599.  
  600.     RToS( errIntercept, str2 );
  601.     stat = stat&& SetVar("errintercept",str2);
  602.     strcat( str1, " errintercept ");
  603.     strcat( str1, str2 );
  604.  
  605.     if (strcmp(command.cmdWord[1],"type")==0 ) {
  606.         WriteLine(str1);
  607.         }
  608.     else if (strcmp(command.cmdWord[1],"keep")==0 ) {
  609.         SToI( command.cmdWord[4], &colz );
  610.         for ( i=1; i<=table.header.rows; i++ ) {
  611.             GetTable(i,colx,&x);
  612.             SetTable(i,colz,(intercept+(slope*x)),FALSE);
  613.             }
  614.         }
  615.     else if (strcmp(command.cmdWord[1],"remove")==0 ) {
  616.                      SToI( command.cmdWord[4], &colz );
  617.             for ( i=1; i<=table.header.rows; i++ ) {
  618.                 GetTable(i,colx,&x);
  619.                 GetTable(i,coly,&y);
  620.                 SetTable(i,colz,y-(intercept+(slope*x)),FALSE);
  621.                 }
  622.         }                   
  623.     else if (strcmp(command.cmdWord[1],"compute")==0 ) {
  624.         ;
  625.         }                   
  626.     else {
  627.         ErrMsg(badModifier);
  628.         }
  629.         
  630.     if( !stat ) {
  631.         ErrMsg("couldnt set variables");
  632.         }
  633. }
  634.  
  635. SortTable()
  636. {
  637.     int sortCol, i, j, k, cmp();
  638.     sortRec *s;
  639.     long bytesNeeded;
  640.     float x;
  641.     
  642.     SToI( command.cmdWord[1], &sortCol );
  643.     if (table.header.interpolated) {
  644.         ErrMsg("cant sort interpolated table");
  645.         }
  646.     if( GoodCol(sortCol)!=0 ) {
  647.         ErrMsg("column not in table");
  648.         }
  649.     bytesNeeded = 6L * (3L + (long)(table.header.rows));
  650.     if( (s=NewPtr(bytesNeeded)) == 0L ) {
  651.         ErrMsg("not enough free memory");
  652.         }
  653.     for( i=1; i<=table.header.rows; i++ ) {
  654.         (s+i)->r = i;
  655.         GetTable( i, sortCol, &x );
  656.         if( NaN(&x) ) {
  657.             (s+i)->v = minfinity; /*nan's sorted to bottom of table*/
  658.             }
  659.         else {
  660.             (s+i)->v = x;
  661.             }
  662.         } /*end for*/
  663.     qsort( (s+1), table.header.rows, 6,  cmp );
  664.     for( j=1; j<=table.header.cols; j++ ) {
  665.         for( i=1; i<=table.header.rows; i++ ) {
  666.             GetTable( (s+i)->r, j, &x );
  667.             (s+i)->v = x;
  668.             }
  669.         for( i=1; i<=table.header.rows; i++ ) {
  670.             SetTable( i, j, (s+i)->v, FALSE );
  671.             }
  672.         } /* end for j */
  673.     DisposPtr(s);
  674. }
  675.  
  676. cmp(a,b)
  677. sortRec *a, *b;
  678. {
  679.     if( (a->v) < (b->v) ) {
  680.         return(-1);
  681.         }
  682.     else if( (a->v) == (b->v) ) {
  683.         return(0);
  684.         }
  685.     else {
  686.         return(1);
  687.         }
  688. }
  689.  
  690. TabInterpolate()
  691. {
  692.     int *ix, *ixy;    /*ix, iy, and z are temporary arrays created on the heap*/
  693.     float *z;
  694.     
  695.     int ndata, npair, col, i, j, k, il, ir, newRows, oldRows;
  696.     int first, found;
  697.     float x, y, t, u, v, w;
  698.     long bytesNeeded;
  699.     char str[cmdWordLen];
  700.  
  701.     if( table.header.interpolated ) {
  702.         ErrMsg("table already interpolated");
  703.         }
  704.     if( table.header.rows < 2 ) {
  705.         ErrMsg("not enough rows");
  706.         }
  707.     if( table.header.cols < 2 ) {
  708.         ErrMsg("not enough cols");
  709.         }
  710.         
  711.     SToR( command.cmdWord[1], &(table.header.samp), FALSE );
  712.     if (table.header.samp<=0)  {
  713.         table.header.samp = 1.0;
  714.         ErrMsg("samp must be > 0");
  715.         }
  716.  
  717.     bytesNeeded = 2L * (3+table.header.maxRows);
  718.     if( (ix=NewPtr(bytesNeeded)) == 0L ) {
  719.         ErrMsg("not enough free memory");
  720.         }
  721.     if( (ixy=NewPtr(bytesNeeded)) == 0L ) {
  722.         DisposPtr(ix);
  723.         ErrMsg("not enough free memory");
  724.         }
  725.     bytesNeeded = 4L * (3+table.header.maxRows);
  726.     if( (z=NewPtr(bytesNeeded)) == 0L ) {
  727.         DisposPtr(ix);
  728.         DisposPtr(ixy);
  729.         ErrMsg("not enough free memory");
  730.         }
  731.         
  732.     ndata = 0;
  733.     first = TRUE;
  734.     for( i=1; i<=table.header.rows; i++ ) {
  735.         GetTable(i,1,&x);
  736.         if (!NaN(&x))  {
  737.             if( first ) {
  738.                 ndata++;
  739.                 *(ix+ndata) = i;
  740.                 first = FALSE;
  741.                 } /*end if first*/
  742.             else { /*not first*/
  743.                 ndata++;
  744.                 *(ix+ndata) = i;
  745.                 GetTable( *(ix+ndata-1), 1, &y );
  746.                 if( x<=y ) {
  747.                     DisposPtr(ix);
  748.                     DisposPtr(ixy);
  749.                     DisposPtr(z);
  750.                     ErrMsg("col 1 does not monotonically increase");
  751.                     } /*end if x<=y*/
  752.                 } /*end if not first*/
  753.             } /*end if not NaN */
  754.         } /*end for*/
  755.  
  756.     if (ndata<2) {
  757.         DisposPtr(ix);
  758.         DisposPtr(ixy);
  759.         DisposPtr(z);
  760.         ErrMsg("not enough good x-values");
  761.         }
  762.         
  763.     GetTable(*(ix+1),1,&(table.header.start));
  764.     GetTable( *(ix+ndata), 1, &t );
  765.     x = 1.0 + ((t-table.header.start)/table.header.samp);
  766.     oldRows = table.header.rows;
  767.     if (   ((long)x)    >   ((long)table.header.maxRows)  ) {                   
  768.         WriteLine("warning. some data lost from end of columns");
  769.         newRows = table.header.maxRows;
  770.         } /*end if*/
  771.     else {
  772.         newRows= (int)x;
  773.         } /*end if*/
  774.  
  775.     for (col=2;  col<=table.header.cols; col++ ) {
  776.         npair = 0;
  777.         for( i=1; i<=ndata; i++ ) {
  778.             GetTable( *(ix+i), col, &x );
  779.                      if (!NaN(&x)) {
  780.                 npair++;
  781.                 *(ixy+npair) = *(ix+i);
  782.                 } /*end if not NaN*/
  783.             } /*end for*/
  784.             
  785.         if (npair<2) {
  786.             IToS( col, str );
  787.             WritePhrase("warning: not enough data in col ");
  788.             WriteLine(str);
  789.             table.header.rows = newRows;
  790.             for( j=1; j<=table.header.rows; j++ ) {
  791.                 SetTable(j,col,infinity,FALSE);
  792.                 }
  793.             table.header.rows=oldRows;
  794.             } /*end if pairs<2*/
  795.         else { /*npairs>=2*/
  796.             il = 1;
  797.             ir = 2;
  798.             for( i=1; i<=newRows; i++ ) {
  799.                 x = table.header.start + table.header.samp*((float)(i-1));
  800.                 if( GetTable(*(ixy+il),1,&t) || (x<t) )  {                   
  801.                     *(z+i) =infinity;
  802.                     } /*end if (x<t)*/
  803.                 else if( GetTable(*(ixy+npair),1,&t) || (x>t) ) {
  804.                     *(z+i) = infinity;
  805.                     }
  806.                 else if( GetTable(*(ixy+il),1,&t) ||  GetTable(*(ixy+ir),1,&u) || ((x>=t)&&(x<=u)) ) {
  807.                     GetTable( *(ixy+il), col, &t );
  808.                     GetTable( *(ixy+ir),col, &u );
  809.                     GetTable( *(ixy+il), 1, &v );
  810.                     GetTable( *(ixy+ir), 1, &w );
  811.                     *(z+i) = t + (((u-t)/(w-v))*(x-v));
  812.                     }
  813.                 else { /*search*/
  814.                     j = il+1;
  815.                     found = FALSE;
  816.                     while( (!found) && (j<=(npair-1)) ) {
  817.                         il = j;
  818.                         ir = j+1;
  819.                         GetTable( *(ixy+il), 1, &t );
  820.                         GetTable( *(ixy+ir), 1, &u );
  821.                         if( (x>=t) && (x<=u) ) {
  822.                             found = TRUE;
  823.                             } /*end in interval*/
  824.                         j++;
  825.                         } /*end while*/
  826.                     GetTable( *(ixy+il), col, &t );
  827.                     GetTable( *(ixy+ir),col, &u );
  828.                     GetTable( *(ixy+il), 1, &v );
  829.                     GetTable( *(ixy+ir), 1, &w );
  830.                     *(z+i) = t + (((u-t)/(w-v))*(x-v));
  831.                     } /*end else search*/
  832.                 } /*end for i*/
  833.             
  834.             table.header.rows = newRows;
  835.             for( i=1; i<=table.header.rows; i++ ) {
  836.                 SetTable( i, col, *(z+i), FALSE );
  837.                 } /*end for i*/
  838.             table.header.rows = oldRows;
  839.  
  840.             } /*end if pairs>=2*/
  841.     } /*end for col*/
  842.     
  843.     table.header.interpolated=TRUE;
  844.     table.header.rows = newRows;
  845.     Header2Vars();
  846.     CreateCol1();
  847.     DisposPtr(ix);
  848.     DisposPtr(ixy);
  849.     DisposPtr(z);
  850. }
  851.